package com.zf.validation.config;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
 * 自定义区域解析器，用于解析区域，找到对应的语言
 */
@Configuration
public class LocaleResolverConfig {

    /**
     * 注入 LocaleResolver，名称必须是 localeResolver，否者不生效。
     * 原因见源码 {@link org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration#localeResolver()}
     * 方法上的 @ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME) 注解
     */
    @Bean
    public LocaleResolver localeResolver() {
        return new MessageLocaleResolver();
    }

    /**
     * LocaleResolver 用来获取语言信息，Spring通过它来选择语言信息配置文件，参数校验的错误信息国际化、应用的国际化都需要它：
     * <pre>
     * 自定义语言解析器:
     *      1、spring默认的语言解析器是{@link AcceptHeaderLocaleResolver} ，他读取 "Accept-Language" 请求头的信息，来构造 Locale，
     *              请求头样例 "Accept-Language:en-US" 。
     *      2、自定义的语言解析器需要注入到容器才能生效，且bean名称必须是 localeResolver，否者不生效，
     *        原因见源码 {@link org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration#localeResolver()}
     *                  方法上的 @ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME) 注解
     *
     * 这里自定义语言解析器，兼容 zh_CN 和 zh-CN 格式，读取 "lang" 请求头中的 语言信息，样例："lang: zh_CN" 或 "lang: zh-CN"
     * <pre/>
     */
    public static class MessageLocaleResolver implements LocaleResolver {
        private static final String LANG = "lang";

        @Override
        public Locale resolveLocale(HttpServletRequest request) {
            // 获取请求头中的语言信息，如zh_CN
            String language = request.getHeader(LANG);
            // 没有头，就使用系统默认语言
            if (StringUtils.isBlank(language)) {
                // 获取系统语言
                return Locale.getDefault();
            }

            // zh-CN格式，
            int dashSepIndex = StringUtils.indexOf(language, "-");
            if (dashSepIndex > 1 && dashSepIndex < language.length() - 1) {
                return new Locale(language.substring(0, dashSepIndex), language.substring(dashSepIndex + 1));
            }

            // zh_CN格式，
            int underscoreSepIndex = StringUtils.indexOf(language, "_");
            if (underscoreSepIndex > 1 && underscoreSepIndex < language.length() - 1) {
                // zh_CN格式，可以直接使用 new Locale("zh_CN") 方法，不需要拆分
                // return new Locale(language);
                return new Locale(language.substring(0, underscoreSepIndex), language.substring(underscoreSepIndex + 1));
            }
            // 都不符合，则获取系统语言
            return Locale.getDefault();
        }

        @Override
        public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

        }
    }
}
